package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.dubbo.api.PeachblossomApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Voice;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.VoiceVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 桃花传音service
 */

@Service
public class PeachblossomService {

    @Autowired//fastDFS的两个对象
    private FastFileStorageClient client;
    @Autowired
    private FdfsWebServer webServer;
    @DubboReference//注入接口
    private PeachblossomApi peachblossomApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private StringRedisTemplate redisTemplate;

    //发送语音消息
    public void sendVoice(MultipartFile soundFile) throws IOException {
        //1.获取到当前用户id（语音发送人的id）
        Long userId = UserHolder.getUserId();
        //2.将语音消息保存到fastDFS中（需要四个参数）
        //2.1 文件输入流
        InputStream inputStream = soundFile.getInputStream();
        //2.2文件大小
        long size = soundFile.getSize();
        //2.3文件后缀名
        String sufix = "mp3";
        //2.4文件元数据（一般情况下元数据为空）
        StorePath path = client.uploadFile(inputStream, size, sufix, null);
        //3.获取部分地址
        String fullPath = path.getFullPath();
        //4.拼接完整地址
        String url = webServer.getWebServerUrl() + "/" + fullPath;
        //5.构建对象
        Voice voice = new Voice();
        voice.setUserId(userId);
        voice.setSoundUrl(url);
        voice.setCreated(System.currentTimeMillis());
        peachblossomApi.save(voice);
    }

    //接收语音消息
    public VoiceVo acceptVoice() {
        //1.获取到当前用户的id
        Long userId = UserHolder.getUserId();
        //2.设置redisKey
        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String redisKey = "VOICE_" + userId ;
        //3.调用方法计算到剩余的收听次数
        Integer count = redisWay(redisKey);
        if (count>=10){
            throw new BusinessException(ErrorResult.voiceError());
        }
        //4.从语音表中间随机查询一个没有被拾取的对象
        Voice voice = peachblossomApi.findByRandomOne(userId);
            //4.1判断一下数据库查询结果，如果为空，就抛出异常
        if (voice==null){
            throw new BusinessException(ErrorResult.voicerError());
        }
        String voiceId = voice.getId().toString();
        //5.获取到对应的用户对象
        UserInfo info = userInfoApi.findById(voice.getUserId());
        //6.构建返回
        VoiceVo vo = VoiceVo.init(info, voice);
        vo.setId(voice.getUserId());
        vo.setRemainingTimes(10-count);
        //7.将每日数据保存到redis中,音频id作为值
        redisTemplate.opsForValue().append(redisKey, voiceId+",");
        //8.获取当前时间距离零点的毫秒值
        long time = getTomorrowZeroSeconds();
        //9.为当前键对应的数据设置存活时间
        redisTemplate.expire(redisKey,time, TimeUnit.MILLISECONDS);
        //10.在返回之前将该条语音的状态设置为已捞取
        peachblossomApi.updateById(voice);
        //11.返回参数
        return vo;
    }

    //定义一个单独的方法，获取redis当中存储的数据
    private Integer redisWay(String redisKey) {
        //构建一个默认返回值
        int count=0;
        //1.依次传入redisKey,hashKey获取到数据
        String redisStr = redisTemplate.opsForValue().get(redisKey);
        //如果不为空，就将数据切割计算长度
        if (!StringUtils.isEmpty(redisStr)){
        //2.将获取到的数据分割成数组
        String[] str = redisStr.split(",");
        //3.返回数组的长度
            count= str.length;
        }
        //返回一个默认值
        return count;
    }


    //获取当前时间到0点的毫秒值
    public static long getTomorrowZeroSeconds() {
        long current = System.currentTimeMillis();// 当前时间毫秒数
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        long tomorrowzero = calendar.getTimeInMillis();
        long tomorrowzeroSeconds = tomorrowzero- current;
        return tomorrowzeroSeconds;
    }
}
